#ifndef T1_UDC_H_
#define T1_UDC_H_

#include "regs.h"
#include "usb.h"
#include "stdint.h"
#include "iodef.h"

#define __IO	volatile
//#define _BIT	MBit
#define EP_IN_INT_SUPPORT

typedef struct {
        __IO uint32_t USB_TOP;
        __IO uint32_t USB_INT_STATE;
        __IO uint32_t EP_INT_STATE;
        __IO uint32_t EP0_INT_STATE;
        __IO uint32_t USB_INT_EN;
        __IO uint32_t EP_INT_EN;
        __IO uint32_t EP0_INT_EN;
        __IO uint32_t resev1;
        __IO uint32_t EPX_INT_STATE[4];
        __IO uint32_t resev2[4];
        __IO uint32_t EPX_INT_EN[4];
        __IO uint32_t resev3[4];
        __IO uint32_t USB_ADDR;
        __IO uint32_t EP_ENABLE;
        __IO uint32_t EP_DIR;
        __IO uint32_t EP_SIZE;
        __IO uint32_t EP_INDEX1_2;
        __IO uint32_t EP_INDEX3_4;
        __IO uint32_t TOG_CTRL1_4;
        __IO uint32_t reserv4;
        __IO uint32_t SETUP[8];
        __IO uint32_t PACKET_SIZE[2];
        __IO uint32_t reserv5[22];
        __IO uint32_t EP_AVAIL[5];
        __IO uint32_t reserv6[3];
        __IO uint32_t DMA_ADDR[4];
        __IO uint32_t DMA_NUM[2];
        __IO uint32_t reserv7[2];
        __IO uint32_t EP_CTRL[5];
        __IO uint32_t reserv8[3];
        __IO uint32_t EP_FIFO[5];
        __IO uint32_t reserv9[3];
        __IO uint32_t EP_MEM;
        __IO uint32_t EP_DMA;
        __IO uint32_t EP_HALT;
}udc_reg_t;

#define USB_TOP_HS              _BIT(0)
#define USB_TOP_CONNECT         _BIT(1)
#define USB_TOP_WAKEUP          _BIT(2)
#define USB_TOP_RESET           _BIT(3)
#define USB_TOP_SUSCLK_EN       _BIT(4)
#define UBS_TOP_ACTIVE          _BIT(7)

#define USB_INT_RESET           _BIT(0)
#define USB_INT_SUSPEND         _BIT(1)
#define USB_INT_RESUME          _BIT(2)
#define USB_INT_SOF             _BIT(3)
#define USB_INT_EP              _BIT(4)
#define USB_INT_DMAEND          _BIT(5)

#define USB_EPn_INT(n)			_BIT(n)
#define USB_INT_EP0             _BIT(0)
#define USB_INT_EP1             _BIT(1)
#define USB_INT_EP2             _BIT(2)
#define USB_INT_EP3             _BIT(3)
#define USB_INT_EP4             _BIT(4)

#define EP_INT_SETUP            _BIT(0)
#define EP_INT_INTIMEOUT        _BIT(0)
#define EP_INT_FINISH           _BIT(1)
#define EP_INT_INNACK           _BIT(2)
#define EP_INT_INACK            _BIT(3)
#define EP_INT_INSTALL          _BIT(4)
#define EP_INT_OUTNACK          _BIT(5)
#define EP_INT_OUTACK           _BIT(6)
#define EP_INT_OUTSTALL         _BIT(7)

#define USB_EP_EN(n)			_BIT(n-1)
#define USB_EN_EP1              _BIT(0)
#define USB_EN_EP2              _BIT(1)
#define USB_EN_EP3              _BIT(2)
#define USB_EN_EP4              _BIT(3)

#define EP_TRANSFER(n)  (0x80 | (n))

#define udc ((udc_reg_t *)T1_USB11_BASE)

#define MAX_PACKAGE_SIZE 64
#define MAX_ENDPOINT     5

#define CDC_EP_IN_NUM			(3)
#define CDC_EP_OUT_NUM			(4)
#define CDC_EP_INT_NUM			(1)
#define CDC_EP_IN_ADDR			USB_ENDPOINT_IN(CDC_EP_IN_NUM)
#define CDC_EP_OUT_ADDR			USB_ENDPOINT_OUT(CDC_EP_OUT_NUM)
#define CDC_EP_INT_ADDR			USB_ENDPOINT_IN(CDC_EP_INT_NUM)

int t1_udc_init(void);
void write_ep_data(int ep, char *in, int num);
int read_ep_data(int ep, char *out, int num);
#ifndef EP_IN_INT_SUPPORT
void wait_ep_in_complete(int ep);
#endif

#endif /* WM02X8_UDC_H_ */
